package com.qing.microservices.shirostudy.common.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import com.qing.microservices.shirostudy.common.matcher.Sm3SimpleCredentialsMatcher;
import com.qing.microservices.shirostudy.realm.CustomizedRealm;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * @author guoqf
 */
@Configuration
public class ShiroConfig {

    /**
     * ShiroFilter: 过滤请求
     *
     * @param webSecurityManager
     * @return
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager webSecurityManager) {
        ShiroFilterFactoryBean factory = new ShiroFilterFactoryBean();
        factory.setSecurityManager(webSecurityManager);

        // 配置授权资源和白名单
        Map<String, String> defMap = new HashMap<>(4);
        defMap.put("/login/login", "anon");
        defMap.put("/user/**", "anon");
        defMap.put("/error/**", "anon");
        defMap.put("/**", "authc");
        factory.setFilterChainDefinitionMap(defMap);
        factory.setUnauthorizedUrl("/error/403");

        // 认证失败跳转页面
        factory.setLoginUrl("/login/login");
        return factory;
    }


    @Bean
    public DefaultWebSecurityManager webSecurityManager(Realm realm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(realm);
        return securityManager;
    }

    @Bean
    public Realm realm() {
        CustomizedRealm realm = new CustomizedRealm();
        CredentialsMatcher matcher = new Sm3SimpleCredentialsMatcher();
        realm.setCredentialsMatcher(matcher);
        return realm;
    }

    @Bean
    public SimpleMappingExceptionResolver exceptionResolver() {
        SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
        Properties mappings = new Properties();
        mappings.setProperty("org.apache.shiro.authz.AuthorizationException", "/error/403");
        resolver.setExceptionMappings(mappings);
        return resolver;
    }

    @Bean
    public ShiroDialect shiroDialect() {
        return new ShiroDialect();
    }
}
